Overview
Nouns DAO will integrate with Octant v2 through the Lido Yield Skimming Strategy — an ERC-4626 vault that captures yield from wstETH exchange rate appreciation (~3-5% APY from ETH staking rewards).
| Component | Purpose | Capital |
|---|---|---|
| Lido Yield Skimming Strategy | Generate yield for public goods funding | wstETH held by treasury |
Architecture Note: The strategy IS the ERC-4626 vault. No MultistrategyVault wrapper is needed since only one strategy is approved by the DAO. This simplifies deployment, reduces gas costs, and eliminates unnecessary complexity.
Prerequisites (Pending Items)
The following items must be resolved before executing the DAO proposal:
| Item | Status | Owner | Notes |
|---|---|---|---|
| Dragon Funding Pool address | ⏳ Pending | Nouns DAO | Strategy donation recipient (PaymentSplitter) |
| Keeper Bot address | ⏳ Pending | Nouns DAO | Strategy keeper for harvesting |
| Emergency Shutdown Admin address | ⏳ Pending | Nouns DAO | Can shutdown strategy and perform emergency withdrawals |
| wstETH deposit amount | ⏳ Pending | Nouns DAO | Amount of wstETH to deposit (treasury holds ~1,725 wstETH) |
⚠️ Action Required: Update this document with actual addresses before submitting the proposal.
Verified On-Chain Addresses
| Entity | Address | Network |
|---|---|---|
| Nouns DAO Treasury (Executor/Timelock) | 0xb1a32FC9F9D8b2cf86C068Cae13108809547ef71 |
Ethereum |
| Nouns DAO Governor Proxy | 0x6f3E6272A167e8AcCb32072d08E0957F9c79223d |
Ethereum |
| Nouns NFT Token | 0x9C8fF314C9Bc7F6e59A9d9225Fb22946427eDC03 |
Ethereum |
| wstETH | 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0 |
Ethereum |
| PaymentSplitter Factory | 0x5711765E0756B45224fc1FdA1B41ab344682bBcb |
Ethereum |
| Tokenized Strategy Implementation | 0x8cf7246a74704bBE59c9dF614ccB5e3d9717d8Ac |
Ethereum |
Lido Yield Skimming Strategy
The LidoStrategy is an ERC-4626 vault (via Yearn's TokenizedStrategy) that tracks wstETH → stETH exchange rate appreciation. Treasury deposits wstETH directly into the strategy.
Underlying Yield Source
wstETH (Wrapped Staked ETH) — Lido's non-rebasing wrapper around stETH.
- Mechanism: Exchange rate increases as staking rewards accrue to stETH
- Rate Source:
wstETH.stEthPerToken()(manipulation-resistant, oracle-free) - Yield: ~3-5% APY from ETH validator staking rewards
- Risk: ETH validator slashing can reduce exchange rate
Yield Capture Mechanism
Role Assignments
| Role | Assigned To | Description |
|---|---|---|
| Management | Nouns DAO Treasury (0xb1a3...ef71) |
Administrative role (set keeper, set emergency admin, shutdown) |
| Keeper | Dedicated Bot/EOA | REQUIRED: Authorized to call report() to harvest yields without governance votes |
| Emergency Admin | Nouns DAO Treasury (0xb1a3...ef71) |
Can shutdown the strategy and perform emergency withdrawals |
Critical: The Keeper should be a dedicated EOA or bot, NOT the Treasury. Assigning Keeper to Treasury would require a governance vote for every harvest (7+ day minimum voting cycle), creating severe operational bottlenecks.
Yield Distribution
| Destination | Allocation |
|---|---|
| Dragon Funding Pool | 100% |
PaymentSplitter (Dragon Funding Pool)
The PaymentSplitter is deployed via the existing factory and receives yield from the strategy.
Recommended Configuration
| Payee | Allocation | Purpose |
|---|---|---|
| Nouns Ecosystem Grants | 100% | Public goods funding |
Note: Multiple payees with different allocations can be configured if desired (e.g., 80% grants, 20% operations).
Nouns DAO Governance
Architecture
Nouns DAO uses a Governor + Timelock pattern with NFT-based voting:
| Component | Address / Value |
|---|---|
| Governor Proxy | 0x6f3E6272A167e8AcCb32072d08E0957F9c79223d |
| Executor (Timelock) | 0xb1a32FC9F9D8b2cf86C068Cae13108809547ef71 |
| Voting Token | Nouns NFT (0x9C8fF314...DC03) |
Execution Call Chain
Critical: From the target contract's perspective, msg.sender is the Executor/Timelock address (0xb1a3...), NOT the Governor. This is why all roles are assigned to the Executor address.
Governance Parameters
See current governance parameters on nouns.wtf/vote.
Voting Platforms
| Platform | Type | Use Case |
|---|---|---|
| nouns.wtf/vote | On-chain | Treasury transactions, contract interactions |
| Discourse | Forum | Discussion, temperature checks |
Execution Playbook
Phase 1: PaymentSplitter Deployment
Deploy a PaymentSplitter to receive yield from the strategy.
Phase 2: Strategy Deployment
The deployment can be executed in a single DAO proposal with 4 batched transactions:
- Deploy PaymentSplitter via Factory
- Deploy LidoStrategy via Factory
- Approve wstETH to Strategy
- Deposit wstETH into Strategy
Note: The strategy factory uses CREATE2, allowing address precomputation.
Note: LidoStrategyFactory needs to be deployed to mainnet first.
Gas Profile
| Component | Gas Cost |
|---|---|
| PaymentSplitter Deployment | ~50k |
| LidoStrategy Deployment | ~3-4M |
| wstETH Approve | ~50k |
| wstETH Deposit | ~200k |
| Total (batched) | ~4M |
| Block Gas Limit | 30M |
| Headroom | >85% |
Transaction Details
Transaction 1: Deploy PaymentSplitter
Target: 0x5711765E0756B45224fc1FdA1B41ab344682bBcb (PaymentSplitter Factory)
Function: createPaymentSplitter(address[],string[],uint256[])
Selector: 0x... (TBD)
Value: 0
Parameters:
payees: [[GRANT_RECIPIENT_ADDRESS]]
payeeNames: ["NounsGrants"]
shares: [100]
Transaction 2: Deploy Strategy
Target: [LIDO_STRATEGY_FACTORY_ADDRESS]
Function: createStrategy(string,address,address,address,address,bool,address)
Selector: 0x... (TBD)
Value: 0
Parameters:
_name: "NounsLidoStrategy"
_management: 0xb1a32FC9F9D8b2cf86C068Cae13108809547ef71
_keeper: [KEEPER_ADDRESS] (dedicated bot)
_emergencyAdmin: [EMERGENCY_ADMIN_ADDRESS]
_donationAddress: [PAYMENT_SPLITTER_ADDRESS]
_enableBurning: false
_tokenizedStrategyAddress: 0x8cf7246a74704bBE59c9dF614ccB5e3d9717d8Ac
Transaction 3: Approve wstETH
Target: 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0 (wstETH)
Function: approve(address,uint256)
Selector: 0x095ea7b3
Value: 0
Parameters:
spender: [STRATEGY_ADDRESS] (from Tx 2)
amount: [DEPOSIT_AMOUNT] (e.g., 1000000000000000000000 for 1000 wstETH)
Transaction 4: Deposit wstETH
Target: [STRATEGY_ADDRESS] (from Tx 2)
Function: deposit(uint256,address)
Selector: 0x6e553f65
Value: 0
Parameters:
assets: [DEPOSIT_AMOUNT] (e.g., 1000000000000000000000 for 1000 wstETH)
receiver: 0xb1a32FC9F9D8b2cf86C068Cae13108809547ef71 (Treasury)
Generate Calldata
forge script partners/nouns_dao/script/GenerateProposalCalldata.s.sol --fork-url $ETH_RPC_URL -vvvv
Post-Deployment Operations
Harvest Operation
Target: [STRATEGY_ADDRESS]
Function: report()
Selector: 0x2606a10b
Value: 0
Calldata: 0x2606a10b
Note: Called by management or keeper to harvest yield. Returns (uint256 profit, uint256 loss).
Mints profit shares to Dragon Router (PaymentSplitter).
Release Yield from PaymentSplitter
Target: [PAYMENT_SPLITTER_ADDRESS]
Function: release(address token, address account)
Selector: 0x... (TBD)
Value: 0
Parameters:
token: [STRATEGY_ADDRESS]
account: [PAYEE_ADDRESS]
Note: Payee calls to claim their share of accumulated yield.
Emergency Operations
Shutdown Strategy
Target: [STRATEGY_ADDRESS]
Function: shutdownStrategy()
Selector: 0xbe8f1668
Effect: Stops new deposits/mints, allows withdrawals.
Access: management or emergencyAdmin
Emergency Withdraw
Target: [STRATEGY_ADDRESS]
Function: emergencyWithdraw(uint256)
Selector: 0x5312ea8e
Parameters:
_amount: Amount to withdraw (up to full balance)
Prerequisite: Strategy must be shutdown first.
Access: management or emergencyAdmin
Standard Withdraw
Target: [STRATEGY_ADDRESS]
Function: withdraw(uint256,address,address)
Selector: 0xb460af94
Value: 0
Parameters:
assets: Amount of wstETH to withdraw
receiver: Address to receive wstETH
owner: 0xb1a32FC9F9D8b2cf86C068Cae13108809547ef71 (Treasury)
Note: Can be called anytime, no lockup period.
Quick Reference: Function Selectors
| Function | Selector | Target | Purpose |
|---|---|---|---|
createPaymentSplitter(...) | TBD | PaymentSplitter Factory | Deploy splitter |
createStrategy(...) | TBD | LidoStrategy Factory | Deploy strategy |
approve(address,uint256) | 0x095ea7b3 | wstETH | Allow spending |
deposit(uint256,address) | 0x6e553f65 | Strategy | Deposit funds |
withdraw(uint256,address,address) | 0xb460af94 | Strategy | Withdraw funds |
report() | 0x2606a10b | Strategy | Harvest yield |
shutdownStrategy() | 0xbe8f1668 | Strategy | Emergency shutdown |
emergencyWithdraw(uint256) | 0x5312ea8e | Strategy | Emergency exit |
Operational Considerations
Keeper Setup
See Role Assignments for Keeper requirements. A dedicated EOA or bot enables autonomous harvesting without governance votes.
Recommended: Set up a keeper bot to call report() periodically (e.g., weekly or monthly) to:
- Update accounting
- Mint yield shares to Dragon Router
- Keep exchange rate tracking accurate
Emergency Admin
The Treasury serves as Emergency Admin. Emergency actions (shutdown, forced withdrawals) will follow standard DAO voting timelines (~7 days) unless a separate multisig is designated for faster response.
Withdrawals
The strategy provides instant liquidity (no lockup). Withdrawals are straightforward:
- Call
withdraw(assets, receiver, owner)orredeem(shares, receiver, owner)on the strategy - Receive underlying wstETH immediately
No unwinding of positions is needed — wstETH is held directly.
Value Debt Tracking
The strategy uses a dual-debt accounting system:
- User Debt: Tracks ETH value owed to depositors
- Dragon Debt: Tracks ETH value owed to Dragon Router (yield recipient)
This ensures:
- Users can always redeem their original value
- Dragon Router only receives actual profit
- Insolvency protection: Dragon operations blocked if vault can't cover user debt
Treasury Holdings (Reference)
Current Nouns DAO treasury holdings (as of snapshot):
| Asset | Amount | Value (USD) |
|---|---|---|
| wstETH | ~1,725 | ~$6.7M |
| rETH | ~163 | ~$600k |
| USDC | ~726k | ~$726k |
| ETH | ~517 | ~$1.6M |
Source: Etherscan Treasury